package com.example.demo.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.Excel.ExcelExportService;
import com.example.demo.mapper.LoginLogMapper;
import com.example.demo.mapper.UserMapper;
import com.example.demo.pojo.Competitions.CompetitionScoreDTO;
import com.example.demo.pojo.R;
import com.example.demo.pojo.User.ExcelUserLoginLogDto;
import com.example.demo.pojo.User.LoginRequest;
import com.example.demo.pojo.User.User;
import com.example.demo.pojo.vip.VipUserDto;
import com.example.demo.service.CompetitionScoreService;
import com.example.demo.service.CompetitionService;
import com.example.demo.service.FundAccountService;
import com.example.demo.service.UserService;
import com.example.demo.utils.TokenUtil.JwtUtils;
import com.example.demo.utils.UserUtil;
import org.apache.poi.ss.formula.functions.T;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/admins")
public class AdminController {

    private static final Logger logger = LoggerFactory.getLogger(AdminController.class);
    @Resource
    private CompetitionScoreService competitionScoreService;

    @Resource
    private UserService userService;

    @Resource
    private CompetitionService competitionService;

    @Autowired
    private ExcelExportService excelExportService;
    @Resource
    private UserUtil userUtil;
    @Resource
    private UserMapper userMapper;
    @Resource
    private FundAccountService fundAccountService;

    @Resource
    private LoginLogMapper loginLogMapper;


    /**
     * 管理员登录接口
     */
    @PostMapping("/login")
    R<T> adminLogin(@RequestBody LoginRequest loginRequest, HttpServletResponse response, HttpServletRequest request) {
        return userService.adminLogin(loginRequest, response, request);
    }

    /**
     * 退出登录接口。
     * 从Cookie中获取用户Token，并处理用户退出登录的逻辑。
     *
     * @param token    用户登录时获取的Token
     * @param response HttpServletResponse对象
     * @return 返回操作结果
     */
    @GetMapping("/outLogin")
    public R<?> adminOtLogin(@CookieValue(name = "token", required = false) String token, HttpServletResponse response) {

        try {
            return userService.adminOtLogin(token, response);
        } catch (Exception e) {
            logger.error("退出失败", e);
            return R.failed("退出失败！");
        }
    }


    /**
     * 管理员修改用户信息接口
     *
     * @param token token
     * @param user  修改的用户信息
     * @return 修改结果
     */
    @PutMapping("/updateUserInfo")
    public R<T> updateUserInfo(@CookieValue(name = "token", required = false) String token
            , @RequestBody User user) {
        if (token == null || token.isEmpty() || !JwtUtils.verifyToken(token)) {
            logger.warn("Token为空");
            return R.failed("管理员未登录或登录异常");
        }

        try {
            return userService.updateUserInfo(token, user);
        } catch (Exception e) {
            logger.error("错误！", e);
            return R.failed("修改用户信息失败");
        }

    }

    /**
     * 管理员获取全体用户信息
     *
     * @param token    token
     * @param pageNum  页码
     * @param pageSize 每页多少用户
     * @return 用户信息
     */
    @PostMapping("/getAllUser")
    public R<Map<String, Object>> getAllUser(@CookieValue(name = "token", required = false) String token
            , @RequestParam int pageNum
            , @RequestParam int pageSize) {
        if (token == null || token.isEmpty() || !JwtUtils.verifyToken(token)) {
            logger.warn("Token为空");
            return R.failed("管理员未登录或登录异常");
        }

        try {
            return userService.getAllUser(pageNum, pageSize);
        } catch (Exception e) {
            logger.error("错误！", e);
            return R.failed("获取用户信息失败");
        }
    }

    /**
     * 用户信息Excel导出
     */
    @GetMapping("/exportUsers")
    public void exportStockPositions(HttpServletResponse response,
                                     @CookieValue(name = "token", required = false) String token) throws IOException {
        File tempFile = null;
        try {
            // 获取并验证Token
            if (token == null || token.isEmpty() || !JwtUtils.verifyToken(token)) {
                throw new Exception("用户未登录或登录异常");
            }

            // 根据Id和userId查询持仓
            QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
            userQueryWrapper.select("nick_name", "real_name", "email",
                            "phone_number", "id_card_number",
                            "School_address", "educational_background",
                            "major", "home_address",
                            "contact_address", "role",
                            "create_time");
            List<User> users = userMapper.selectList(userQueryWrapper);

            // 创建临时文件
            tempFile = File.createTempFile("users_", ".xlsx");

            // 导出数据到临时文件
            excelExportService.exportUser(users, tempFile.getAbsolutePath());

            // 设置响应头
            String fileName = "用户信息.xlsx";
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            String file = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + file);

            // 从临时文件读取数据并写入响应
            Files.copy(tempFile.toPath(), response.getOutputStream());
        } catch (Exception e) {
            // 异常处理
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "导出Excel失败");
        } finally {
            // 删除临时文件
            if (tempFile != null) {
                tempFile.delete();
            }
        }
    }

    /**
     * 用户登录日志Excel导出
     */
    @GetMapping("/exportUsersLoginLog")
    public void exportUserLoginLog(HttpServletResponse response,
                                     @CookieValue(name = "token", required = false) String token) throws IOException {
        File tempFile = null;
        try {
            // 获取并验证Token
            if (token == null || token.isEmpty() || !JwtUtils.verifyToken(token)) {
                throw new Exception("用户未登录或登录异常");
            }

            //查询用户登录日志
            List<ExcelUserLoginLogDto> userLoginLogDtos = loginLogMapper.selectUserLoginLog();


            // 创建临时文件
            tempFile = File.createTempFile("users_login_log", ".xlsx");

            // 导出数据到临时文件
            excelExportService.exportUserLoginLog(userLoginLogDtos, tempFile.getAbsolutePath());

            // 设置响应头
            String fileName = "用户登录日志.xlsx";
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            String file = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + file);

            // 从临时文件读取数据并写入响应
            Files.copy(tempFile.toPath(), response.getOutputStream());
        } catch (Exception e) {
            // 异常处理
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "导出Excel失败");
        } finally {
            // 删除临时文件
            if (tempFile != null) {
                tempFile.delete();
            }
        }
    }

    /**
     * 管理员获取用户详细信息接口
     *
     * @param id    用户id
     * @param token token
     * @return 用户详细信息
     */
    @GetMapping("/getUserById/{id}")
    public R<User> getUserById(@PathVariable Integer id
            , @CookieValue(name = "token", required = false) String token) {
        if (token == null || token.isEmpty() || !JwtUtils.verifyToken(token)) {
            logger.warn("Token为空");
            return R.failed("管理员未登录或登录异常");
        }

        try {
            return userService.getUserById(id);
        } catch (Exception e) {
            logger.error("错误！", e);
            return R.failed("获取用户信息失败");
        }

    }

    /**
     * 管理员禁用用户
     *
     * @param id    用户id
     * @param token token
     * @return 禁用结果
     */
    @PostMapping("/banUserById")
    public R<T> banUserById(@RequestParam Integer id
            , @CookieValue(name = "token", required = false) String token) {
        if (token == null || token.isEmpty() || !JwtUtils.verifyToken(token)) {
            logger.warn("Token为空");
            return R.failed("管理员未登录或登录异常");
        }

        try {
            return userService.banUserById(id);
        } catch (Exception e) {
            logger.error("错误！", e);
            return R.failed("禁用用户失败");
        }
    }

    /**
     * 管理员获取比赛接口
     *
     * @param token    token
     * @param pageNum  页码
     * @param pageSize 每页条数
     * @return 比赛集合
     */
    @GetMapping("/getAllCompetition")
    public R<Map<String, Object>> getAllCompetition(@CookieValue(name = "token", required = false) String token
            , @RequestParam int pageNum, @RequestParam int pageSize) {

        if (token == null || token.isEmpty() || !JwtUtils.verifyToken(token)) {
            logger.warn("Token为空");
            return R.failed("管理员未登录或登录异常");
        }

        try {
            return userService.getAllCompetition(pageNum, pageSize);
        } catch (Exception e) {
            logger.error("错误！", e);
            return R.failed("获取比赛失败");
        }
    }

    /**
     * 获取参赛用户接口
     *
     * @param token token
     * @param id    比赛id
     * @return 参赛用户
     */
    @GetMapping("/getJoinCompetitionUserById")
    public R<Map<String, Object>> getJoinCompetitionUserById(@CookieValue(name = "token", required = false) String token
            , @RequestParam int id
            , @RequestParam int pageNum
            , @RequestParam int pageSize) {
        if (token == null || token.isEmpty() || !JwtUtils.verifyToken(token)) {
            logger.warn("Token为空");
            return R.failed("管理员未登录或登录异常");
        }

        try {
            return competitionService.getJoinCompetitionUserById(id, pageNum, pageSize);
        } catch (Exception e) {
            logger.error("错误！", e);
            return R.failed("获取参赛用户失败");
        }
    }

    /**
     * 获取当天活跃用户数量
     *
     * @param token token
     * @return 用户数量
     */
    @GetMapping("/getCountTodayActiveUsers")
    public R<Long> getCountTodayActiveUsers(@CookieValue(name = "token", required = false) String token) {
        if (token == null || token.isEmpty() || !JwtUtils.verifyToken(token)) {
            logger.warn("Token为空");
            return R.failed("管理员未登录或登录异常");
        }

        try {
            return userService.getCountTodayActiveUsers();
        } catch (Exception e) {
            logger.error("错误！", e);
            return R.failed("获取失败");
        }
    }

    /**
     * 获取昨日的活跃用户数目
     *
     * @param token token
     * @return 数量
     */
    @GetMapping("/getCountYesterdayActiveUsers")
    public R<Long> getCountYesterdayActiveUsers(@CookieValue(name = "token", required = false) String token) {
        if (token == null || token.isEmpty() || !JwtUtils.verifyToken(token)) {
            logger.warn("Token为空");
            return R.failed("管理员未登录或登录异常");
        }

        try {
            return userService.getCountYesterdayActiveUsers();
        } catch (Exception e) {
            logger.error("错误！", e);
            return R.failed("获取失败");
        }
    }

    /**
     * 获取一定时间内活页的用户数目
     *
     * @param token token
     * @param time  天数（一天或者其他天数）
     * @return 数目
     */
    @GetMapping("/getActiveUsersCounts")
    public R<Long> getActiveUsersCounts(@CookieValue(name = "token", required = false) String token
            , @RequestParam Integer time) {
        if (token == null || token.isEmpty() || !JwtUtils.verifyToken(token)) {
            logger.warn("Token为空");
            return R.failed("管理员未登录或登录异常");
        }

        try {
            return userService.getActiveUsersCounts(time);
        } catch (Exception e) {
            logger.error("错误！", e);
            return R.failed("获取失败");
        }
    }

    /**
     * 获取快到期vip用户
     *
     * @param token token
     * @return 用户列表
     */
    @GetMapping("/getExpireVipUsers")
    public R<List<VipUserDto>> getExpireVipUsers(@CookieValue(name = "token", required = false) String token) {
        if (token == null || token.isEmpty() || !JwtUtils.verifyToken(token)) {
            logger.warn("Token为空");
            return R.failed("管理员未登录或登录异常");
        }

        try {
            return userService.getExpireVipUsers();
        } catch (Exception e) {
            logger.error("错误！", e);
            return R.failed("获取失败");
        }
    }

    /**
     * 获取比赛所有银行账户接口
     *
     * @param token    token
     * @param id       比赛id
     * @param pageNum  页码
     * @param pageSize 每页数量
     */
    @GetMapping("/getAllFundAccountsList")
    public R<Map<String, Object>> getAllFundAccountsList(@CookieValue(name = "token", required = false) String token
            , @RequestParam int id
            , @RequestParam int pageNum
            , @RequestParam int pageSize) {
        if (token == null || token.isEmpty() || !JwtUtils.verifyToken(token)) {
            logger.warn("Token为空");
            return R.failed("管理员未登录或登录异常");
        }

        try {
            return fundAccountService.getAllFundAccountsList(id, pageNum, pageSize);
        } catch (Exception e) {
            logger.error("错误！", e);
            return R.failed("获取银行账户失败");
        }
    }

    /**
     * 获取比赛所有比赛账户接口
     *
     * @param token    token
     * @param id       比赛id
     * @param pageNum  页码
     * @param pageSize 每页数量
     */
    @GetMapping("/getAllUserFundAccountsList")
    public R<Map<String, Object>> getAllUserFundAccountsList(@CookieValue(name = "token", required = false) String token
            , @RequestParam int id
            , @RequestParam int pageNum
            , @RequestParam int pageSize) {
        if (token == null || token.isEmpty() || !JwtUtils.verifyToken(token)) {
            logger.warn("Token为空");
            return R.failed("管理员未登录或登录异常");
        }

        try {
            return fundAccountService.getAllUserFundAccountsList(id, pageNum, pageSize);
        } catch (Exception e) {
            logger.error("错误！", e);
            return R.failed("获取比赛账户失败");
        }
    }

    /**
     * 获取管理员登录日志
     * @param pageNum 页数
     * @param pageSize 每页条数
     * @return 管理员登录日志
     */
    @GetMapping("/getAdminLoginLog")
    public R<Map<String, Object>> getAdminLoginLog(@RequestParam int pageNum, @RequestParam int pageSize){
        try {
            return userService.getAdminLoginLog(pageNum,pageSize);
        } catch (Exception e) {
            logger.error("错误！", e);
            return R.failed("获取失败");
        }
    }

    /**
     * 获取用户登录日志
     * @param pageNum 页数
     * @param pageSize 每页条数
     * @return 用户登录日志
     */
    @GetMapping("/getUserLoginLog")
    public R<Map<String, Object>> getUserLoginLog(@RequestParam int pageNum, @RequestParam int pageSize){
        try {
            return userService.getUserLoginLog(pageNum,pageSize);
        } catch (Exception e) {
            logger.error("错误！", e);
            return R.failed("获取失败");
        }
    }

    /**
     * 获取比赛排名接口
     *
     * @param token token
     * @param id    比赛id
     */
    @PostMapping("/getCompetitionScoreById")
    public R<List<CompetitionScoreDTO>> getCompetitionScoreById(@CookieValue(name = "token", required = false) String token
            , @RequestParam Integer id) {
        if (token == null || token.isEmpty() || !JwtUtils.verifyToken(token)) {
            logger.warn("用户未登录或Token无效");
            return R.failed("用户登录异常或未登录！");
        }
        try {
            return competitionScoreService.getCompetitionScoreById(token, id);
        } catch (Exception e) {
            logger.error("获取比赛排名失败", e);
            return R.failed("获取比赛排名失败");
        }
    }

}
